/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.tencent.tendon.convert.json;

/**
 *
 * @author nbzhang
 */
public final class JsonEnumListener<E extends Enum> extends JsonListener<E> {

    private final Class<E> type;

    private final Entity<E>[] values;

    @SuppressWarnings("unchecked")
    public JsonEnumListener(Class<E> type) {
        this.type = type;
        E[] enums = type.getEnumConstants();
        this.values = new Entity[enums.length];
        for (int i = 0; i < values.length; i++) {
            E item = enums[i];
            this.values[i] = new Entity<E>(item.name().toCharArray(), item);
        }
    }

    @Override
    public void convertTo(final JsonWriter out, final E value) {
        if (value == null) {
            out.writeNull();
        } else {
            for (int i = 0; i < values.length; i++) {
                if (value == values[i].value) {
                    out.write(values[i].quotekey);
                    return;
                }
            }
            out.writeNull();
        }
    }

    @Override
    public E convertFrom(final JsonReader in) {
        char[] text = in.readValue();
        if (text == null) return null;
        for (int i = 0; i < values.length; i++) {
            if (equals(text, 0, text.length, values[i].key)) return values[i].value;
        }
        return null;
    }

    private static boolean equals(char[] a, int start, int length, char[] a2) {
        if (a2.length != length) return false;
        for (int i = 0; i < length; i++) {
            if (a[i + start] != a2[i]) return false;
        }
        return true;
    }

    @Override
    public Class<E> getType() {
        return type;
    }

    private final class Entity<E> {

        public final char[] key;

        public final char[] quotekey;

        public final E value;

        public Entity(char[] key, E value) {
            this.key = key;
            this.value = value;
            char[] str = new char[key.length + 2];
            str[0] = '"';
            System.arraycopy(key, 0, str, 1, key.length);
            str[key.length + 1] = '"';
            this.quotekey = str;
        }
    }
}
